package com.gopay.checkorder.service.task;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.gopay.checkorder.dao.BisBankOrderQueryDAO;
import com.gopay.checkorder.service.BankOrderService;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BankOrderType;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.util.CommonUtils;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.BankInteractRemoteService;
/**
 * 
 * 退款订单定时发送银行任务
 * @RefundOrderSendBankJob.java
 * @author lilili
 * @2016-11-8 上午11:50:46 www.gopay.com.cn Inc.All rights reserved.
 */
public class RefundOrderSendBankJob implements Task {

	 private final static Logger logger = LoggerFactory.getLogger(RefundOrderSendBankJob.class);

	    private final static int MAX_SIZE = 10000;

	    @Resource(name = "bisBankOrderQueryDAO")
	    private BisBankOrderQueryDAO bisBankOrderQueryDAO;
	    
	    @Resource(name = "bankOrderService")
	    private BankOrderService bankOrderService;
	    
	    @Resource(name = "bankClient")
	    private BankInteractRemoteService bankClient;

	    private void printLog(StopWatch sw, String prefix) {
	        sw.split();
	        logger.error(prefix + "------,耗时=" + sw.getSplitTime());
	    }

	
	@Override
	public void doTask() {
		try {
		    StopWatch sw=new StopWatch();
		    sw.start();
		    	  
		    printLog(sw, "RefundOrderSendBankJob------start");
            int count = 0;

            Date date = new Date();
            int resCount = getSendBankOrderCount(date);
            printLog(sw, "RefundOrderSendBankJob------退款发往银行订单总数量=" + resCount);
            List<BankOrder> list = null;
            if (count < resCount) {
                list = getSendOrders(date);
                printLog(sw, "RefundOrderSendBankJob------list.size()=" + list.size() + ",count=" + count);
            }
            
            if(list != null){
	            for (BankOrder bankOrder : list) {
	            	BaseMessage base = new BaseMessage();
	            	try{
	            	Result result = null;
	            	logger.error("退款 发送银行--开始 ，orderId="+bankOrder.getOrderId());
	            	base.setOrderId(bankOrder.getOrderId());
	            	base.setBankOrderId(bankOrder.getOutOrderId());
	            	base.setTkOriBankOrderId(bankOrder.getOriOutOrderId());
	            	base.setAmount(bankOrder.getSendBankAmt());
		            base.setOrderDate(CommonUtils.formatDate(new Date(),
		                    "yyyyMMddhhmmss"));
					result =bankClient.sendBankRefund(base);
					logger.error("退款 发送银行--结束 ，orderId="+bankOrder.getOrderId()+",resultCode="+result.getResultCode());
	            	}catch(Exception e){
	            		logger.error("发送银行异常 ，orderId="+base.getOrderId(),e);
	            	}
	            }
            }
            
		}catch(Exception e){
			logger.error("RefundOrderSendBankJob 退款发送银行任务异常", e);
		}

	}
	
	 /**
     * 已受理订单笔数
     * 
     * @param orderStatus
     * @return
     */
    protected int getSendBankOrderCount(Date date) {
        Map<String, Object> params = new HashMap<String, Object>();
        StringBuffer hql = new StringBuffer("select count(*) ");
        hql.append(buildHqlAndParamsOfCorpRefund(params));

        int resCount = bisBankOrderQueryDAO.findCountByHql(hql.toString(), params);
        if (resCount > MAX_SIZE) {
            resCount = MAX_SIZE;
        }
        return resCount;
    }

    /**
     * 查询已受理订单笔数
     * @param date
     * @return
     */
    protected List<BankOrder> getSendOrders(Date date) {
    	List<BankOrder> resultList = new ArrayList<BankOrder>();
        Map<String, Object> params = new HashMap<String, Object>();

        StringBuilder sb = new StringBuilder();
        sb.append(buildHqlAndParamsOfCorpRefund(params));
        List<BankOrder> bankOrderList = bisBankOrderQueryDAO.findByHql(sb.toString(), params);
        for (BankOrder bankOrder : bankOrderList) {
        	if(BankConstants.BANK_LOGO_PAB.equals(bankOrder.getBankCode())
        			&& !isCanDoPabExPayRefund(bankOrder.getOriOutOrderId())){
        		logger.error("平安快捷退款订单(" + bankOrder.getOrderId() + ")只能次日退款，等待至次日发送报文！");
        		continue;
        	}
        	resultList.add(bankOrder);
        }
        return resultList;
    }
    
    private boolean isCanDoPabExPayRefund(String oriOutOrderId){
    	Map<String, Object> params = new HashMap<String, Object>();
    	StringBuilder hql = new StringBuilder();
    	hql.append(" from BankOrder ");
        hql.append(" where outOrderId = :outOrderId ");
        
        params.put("outOrderId", oriOutOrderId);

        List<BankOrder> bankOrderList = bisBankOrderQueryDAO.findByHql(hql.toString(), params);
        BankOrder oriBankOrder = new BankOrder();
        if(!CollectionUtils.isEmpty(bankOrderList)){
        	oriBankOrder = bankOrderList.get(0);
        }
        if(BisBankBusinessProd._15.value.equals(oriBankOrder.getBankBizProdCode())
        		&& BisBankInterfaceChannel._00.value.equals(oriBankOrder.getInterfaceChennelCode())
        		&& BankConstants.BANK_LOGO_PAB.equals(oriBankOrder.getBankCode())
        		&& new Date().after(getNextDay21Time(oriBankOrder.getSendBankTm()))){
        	return true;
        }
    	return false;
    }
    
    public static void main(String[] args) {
		String strDate ="20171212093549";
		Date sendDate = getNextDay21Time(DateUtils.convertDate("yyyyMMddHHmmss", strDate));
		System.out.println(DateUtils.format(sendDate));
	}
    
    /**
     * 获取第二天晚上23时50分的时间
     * @param date
     * @return
     */
    private static Date getNextDay21Time(Date date){
    	Calendar todayEnd = Calendar.getInstance();
    	todayEnd.setTime(date);
    	todayEnd.add(Calendar.DATE, 1);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 50);
        todayEnd.set(Calendar.SECOND, 0);
        todayEnd.set(Calendar.MILLISECOND, 0);
    	return todayEnd.getTime();
    }

    private Object buildSqlAndParamsOfCorpRefund(Map<String, Object> params) {
		StringBuffer sql = new StringBuffer("");
		return null;
	}


	private String buildHqlAndParamsOfCorpRefund(Map<String, Object> params) {
        StringBuffer hql = new StringBuffer("");
        hql.append(" from BankOrder ");
        hql.append(" where orderStatus = :orderStatus11 ");
        hql.append(" and bankBizProdCode = :bankBizProdCode  ");
        hql.append(" and orderType = :orderType ");
        hql.append(" and sendBankTm >to_date(:beginTime,'yyyyMMddHH24miss') ");

        // map
        params.put("orderStatus11", BankOrderStatus.ACCEPTED);
        params.put("bankBizProdCode", BisBankBusinessProd._12.value);
        params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);

        // 开始时间--最近1天
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        params.put("beginTime", DateUtils.format(calendar.getTime(), "yyyyMMddHHmmss"));

        return hql.toString();
    }

}
